package com.njtoyo.taxi.admin.service.business.customer.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.njtoyo.taxi.admin.library.Const;
import com.njtoyo.taxi.admin.library.common.Enum;
import com.njtoyo.taxi.admin.library.common.OperationRecordHelper;
import com.njtoyo.taxi.admin.library.taxi_service.TaxiService;
import com.njtoyo.taxi.admin.logic.business.CustomerLogic;
import com.njtoyo.taxi.admin.mapper.master.entity.CustomerLogoutLog;
import com.njtoyo.taxi.admin.mapper.master.entity.Ride;
import com.njtoyo.taxi.admin.mapper.master.entity.User;
import com.njtoyo.taxi.admin.mapper.master.enums.CustomerLogoutLogState;
import com.njtoyo.taxi.admin.mapper.master.mapper.CustomerLogoutLogMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.RideMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.UserMapper;
import com.njtoyo.taxi.admin.rest.presenter.business.CustomerLogoutListPresenter;
import com.njtoyo.taxi.admin.rest.presenter.platfrom.DataAuthSqlWhere;
import com.njtoyo.taxi.admin.rest.wrapper.business.customer.ReasonWrapper;
import com.njtoyo.taxi.admin.rest.wrapper.business.customer.logout.IndexQueryWrapper;
import com.njtoyo.taxi.admin.service.business.customer.CustomerLogoutService;
import com.njtoyo.taxi.admin.utils.AuthUtil;
import com.taxi.entity.common.RestResult;
import com.taxi.entity.common.ResultEnum;
import com.njtoyo.taxi.entity.backend.AdminUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.Objects;

import static cn.hutool.json.JSONUtil.toJsonStr;

@Service
@DS(Const.PRIMARY_DS)
@Slf4j
public class CustomerLogoutServiceImpl implements CustomerLogoutService {

    @Autowired
    private CustomerLogoutLogMapper customerLogoutLogMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RideMapper rideMapper;

    @Autowired
    private TaxiService taxiService;

    @Autowired
    private OperationRecordHelper operationRecordHelper;

    @Autowired
    private CustomerLogic customerLogic;

    @Override
    public RestResult<IPage<CustomerLogoutListPresenter>> getAllPage(IndexQueryWrapper listWrapper) {
        listWrapper.addOrder(OrderItem.desc("id"));
        DataAuthSqlWhere dataAuthSqlWhere = AuthUtil.getDataAuthSqlWhere();
        if(CollUtil.isNotEmpty(dataAuthSqlWhere.getAreaIds())){
            listWrapper.setAreaIds(dataAuthSqlWhere.getAreaIds());
        }
        IPage<CustomerLogoutListPresenter> res = customerLogoutLogMapper.getList(listWrapper);
        return RestResult.success(res);
    }

    @Override
    public RestResult agree(AdminUser adminUser, Long id) {
        CustomerLogoutLog logout = customerLogoutLogMapper.selectById(id);
        if (Objects.isNull(logout)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }
        if (!logout.getLogoutState().equals(CustomerLogoutLogState.processing)) {
            return RestResult.failed("此申请不处于待审核状态");
        }
        User customer = userMapper.selectById(logout.getCustomerId());
        if (Objects.isNull(customer)) {
            return RestResult.failed(String.format("乘客 %s 不存在", logout.getCustomerId()));
        }
        // 空驶费订单
        Ride nonePayRide = rideMapper.getNonePayCancelOrderByCustomerId(customer.getId());
        if (Objects.nonNull(nonePayRide)) {
            return RestResult.failed(String.format("存在未支付的空驶费订单，行程ID: %s", nonePayRide.getId()));
        }
        // 订单行程
        Ride undoneRide = rideMapper.getUndoneRideByCustomerId(customer.getId());
        if (Objects.nonNull(undoneRide)) {
            return RestResult.failed(String.format("存在未结束的行程，行程ID: %s", undoneRide.getId()));
        }
        log.info("乘客注销数据清理开始 {}", logout);
        customerLogic.handleLogout(logout);
        log.info("乘客注销数据清理结束");
        operationRecordHelper.addBusinessLog(String.format("同意注销申请 [%s]", logout.getId()));
        taxiService.clearCustomerCache(customer);
        taxiService.sendSmsMessage(Enum.SmsMsgCategory.logout, customer.getMobileNumber());

        return RestResult.success();
    }

    @Override
    public RestResult reject(AdminUser adminUser, Long id) {
        CustomerLogoutLog logout = customerLogoutLogMapper.selectById(id);
        if (Objects.isNull(logout)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }
        if (!logout.getLogoutState().equals(CustomerLogoutLogState.processing)) {
            return RestResult.failed("此申请不处于待审核状态");
        }

        new LambdaUpdateChainWrapper<>(customerLogoutLogMapper)
                .eq(CustomerLogoutLog::getId, logout.getId())
                .set(CustomerLogoutLog::getLogoutState, CustomerLogoutLogState.reject)
                .set(CustomerLogoutLog::getAdoptTimestamp, System.currentTimeMillis() / 1000)
                .update();

        operationRecordHelper.addBusinessLog(String.format("拒绝注销申请 [%s]", logout.getId()));

        return RestResult.success();
    }

    /**
     * 填写注销原因
     * @param id
     * @return
     */
    @Override
    public RestResult reason(Long id, ReasonWrapper wrapper) {
        String reason = wrapper.getReason();
        CustomerLogoutLog logout = customerLogoutLogMapper.selectById(id);
        if (Objects.isNull(logout)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }
        if (!logout.getLogoutState().equals(CustomerLogoutLogState.processing)) {
            return RestResult.failed("此申请不处于待审核状态");
        }
        if(!logout.getLogoutReason().equals("[]")){
            return RestResult.failed("注销原因已经填写,无需再次修改");
        }
        ArrayList<String> list = new ArrayList<>();
        list.add(reason);
        new LambdaUpdateChainWrapper<>(customerLogoutLogMapper)
                .eq(CustomerLogoutLog::getId, logout.getId())
                .set(CustomerLogoutLog::getLogoutReason, toJsonStr(list))
                .set(CustomerLogoutLog::getUpdatedAt, new Date())
                .update();
        return RestResult.success();
    }
}
